home *** CD-ROM | disk | FTP | other *** search
- #include "stdlib.h"
- #include "ask_man.h"
- #include <dos.h>
-
- int indexNo;
-
- ////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////
- KH_AskManager::KH_AskManager(char** tableNames, KH_QUERRY** querries, int num)
- {
- unlink("answer.db");
- unlink("answer1.db");
- querryList = querries;
- workTable = NULL;
- answerTable = NULL;
- numberOfTables = num;
- tables = (KH_PXTable**)malloc(num * sizeof(KH_PXTable**));
- for(int i = 0; i < num; i++)
- tables[i] = new KH_PXTable(tableNames[i]);
- }
- /////////////////////////////////
- KH_AskManager::~KH_AskManager()
- {
- for(int i = 0; i < numberOfTables; i++)
- delete tables[i];
- delete tables;
- delete answerTable;
- delete workTable;
- }
-
- /////////////////////////////////
- int KH_AskManager::createAnswerTable(int nOT)
- {
- pxErr = PXTblDelete("answer.db");
- KH_STRTABLE* fields = new KH_STRTABLE(0, NULL);
- KH_STRTABLE* types = new KH_STRTABLE(0, NULL);
- int dupNo; // Number of duplicated fields
- int dupLen; // Len of addition to fld name (if duplicated)
- char dupBuf[10]; // Buffer for name addition (if duplicated)
- char fld[26];
- for(int i = 0; i < nOT; i++)
- {
- for(int j = 1; j <= tables[i]->nFlds; j++)
- {
- PXFldName(tables[i]->tblHandle, j, 26, fld);
- fields->add(fld);
- char typ[26];
- PXFldType(tables[i]->tblHandle, j, 26, typ);
- types->add(typ);
- }
- }
- //////////////// Test for duplicated field names ////////////////////
- for(i = 0; i < fields->used; i++)
- {
- dupNo = 0;
- for(int j = i + 1; j < fields->used; j++)
- {
- if(!strcmp((*fields)[i], (*fields)[j]))
- dupNo++;
- else
- continue;
- if(dupNo != 0)
- {
- int l = strlen((*fields)[j]);
- dupLen = strlen(itoa(dupNo, dupBuf, 10));
- fields->strings[j] = (char*)realloc(fields->strings[j],
- l + dupLen + 1);
- strcpy(fields->strings[j] + l, dupBuf);
- fields->strings[j][l + dupLen] = '\0';
- }
-
- }
- }
- //////////////////////// End of duplication test /////////////////////////
- if((pxErr = PXTblCreate("answer.db", fields->used, fields->strings,
- types->strings)) != PXSUCCESS)
- {
- delete fields;
- delete types;
- return 0;
- }
-
- delete fields;
- delete types;
- return 1;
- }
-
- /////////////////////////////////
- int KH_AskManager::checkQuerry()
- {
- int totalCheckers = 0;
- /* First of all we check the number of checked or calculated fields
- in the querry. Querry with no checked fields is invalid.
- */
- for(int i = 0; i < numberOfTables; i++)
- for(int j = 1; j <= tables[i]->nFlds; j++)
- {
- if(querryList[i]->checkedFields[j] != QFREE)
- {
- totalCheckers++;
- break;
- }
- }
- if(!totalCheckers)
- {
- khPxErr = 1;
- return 0;
- }
- /* Then we iterates EXAMPLES.
- Second table MUST contain common variable(s)
- with 1-st, third - with the 1-st or 2-nd and so on. If this
- condition fails, querry fails too, because one of tables is not
- linked with others.
- */
- if(numberOfTables == 1)
- return 1;
- for(i = 1; i < numberOfTables; i++)
- for(int k = 0; k < querryList[i]->examples->used; k++)
- for(int j = 0; j < i; j++)
- for(int l = 0; l < querryList[j]->examples->used; l++)
- if(!strcmp((*(querryList[j]->examples))[l],
- (*(querryList[i]->examples))[k]))
- return 1;
- khPxErr = 2;
- return 0;
- }
- /////////////////////////////////
- KH_STRTABLE* KH_AskManager::makeQuerry(int n)
- {
- KH_STRTABLE* retQuerry = new KH_STRTABLE(0, NULL);
-
- int qnum = 0;
- for(int i = 0; i < tables[n]->nFlds; i++)
- if(querryList[n]->querryNumbers[0] != NULL
- && querryList[n]->querryNumbers[qnum] == i)
- {
- retQuerry->add((*(querryList[n]->querry))[qnum]);
- qnum++;
- }
- else
- retQuerry->add("");
- return retQuerry;
- }
-
- /////////////////////////////////
- int KH_AskManager::processSingleTable()
- {
- KH_STRTABLE* completeQuerry = makeQuerry(0);
- int result;
- KH_PXFLD* ret;
- int r = 0;
-
- while(result = tables[0]->Find(completeQuerry->strings))
- {
- pxErr = PXRecBufCopy(tables[0]->recHandle, answerTable->recHandle);
-
- if((pxErr = PXRecAppend(answerTable->tblHandle, answerTable->recHandle))
- != PXSUCCESS)
- break;
- r = 1;
- if(result == 2)
- break;
- }
-
- delete completeQuerry;
- return r;
- }
- /////////////////////////////////
- KH_STRTABLE* KH_AskManager::getCurrExamples(int n)
- {
- KH_STRTABLE* ret = new KH_STRTABLE(0, NULL);
-
- int eNum = 0;
- for(int j = 0; j < tables[n]->nFlds; j++)
- {
- if(querryList[n]->exampleNumbers[eNum] == j)
- ret->add((*(querryList[n]->examples))[eNum]);
- else
- ret->add("");
- }
- return ret;
- }
- /////////////////////////////////
- KH_STRTABLE* KH_AskManager::getExamples(int n)
- {
- KH_STRTABLE* ret = new KH_STRTABLE(0, NULL);
-
- int eNum = 0;
- for(int i = 0; i < n; i++)
- for(int j = 0; j < tables[i]->nFlds; j++)
- {
- if(querryList[i]->exampleNumbers[eNum] == j)
- ret->add((*(querryList[i]->examples))[eNum]);
- else
- ret->add("");
- }
- return ret;
- }
-
- /////////////////////////////////
- int KH_AskManager::getExSrc(KH_STRTABLE* ex, KH_STRTABLE* cur, int* eNums,
- FIELDHANDLE* exFlds)
- {
- int k = 0;
- for(int i = 0; i < cur->used; i++)
- for(int j = 0; j < ex->used; j++)
- {
- if((*ex)[j][0] == '\0'
- || strcmp((*ex)[j], ((*cur)[i])))
- continue;
-
- eNums[k] = i + 1;
- eNums[k + 1] = j + 1;
- exFlds[k / 2] = j + 1;
- k += 2;
- }
- return k;
- }
- /////////////////////////////////
- int KH_AskManager::moveToRec(int* eNums, int numEx, int n, int mode,
- FIELDHANDLE compSecIndexHandle)
- {
- char fieldType[20];
- char _fieldType[20];
- RECORDHANDLE rch;
- pxErr = PXRecBufOpen(workTable->tblHandle, &rch);
- for(int i = 0; i < numEx; i += 2)
- {
- pxErr = PXFldType(workTable->tblHandle, eNums[i + 1], 20,
- fieldType);
- pxErr = PXFldType(tables[n]->tblHandle, eNums[i], 20,
- _fieldType);
- if(fieldType[0] != _fieldType[0])
- {
- khPxErr = 3;
- pxErr = PXRecBufClose(rch);
- return 0;
- }
- switch(fieldType[0])
- {
- case 'A':
- char buf1[255];
- pxErr = PXGetAlpha(tables[n]->recHandle, eNums[i],
- 255, buf1);
- pxErr = PXPutAlpha(rch, eNums[i + 1], buf1);
- break;
- case 'N':
- double d1;
- pxErr = PXGetDoub(tables[n]->recHandle, eNums[i], &d1);
- pxErr = PXPutDoub(rch, eNums[i + 1], d1);
- break;
- case 'S':
- short sh1;
- pxErr = PXGetShort(tables[n]->recHandle, eNums[i], &sh1);
- pxErr = PXPutShort(rch, eNums[i + 1], sh1);
- break;
- case 'D':
- long date1;
- pxErr = PXGetDate(tables[n]->recHandle, eNums[i], &date1);
- pxErr = PXPutDate(rch, eNums[i + 1], date1);
- break;
- default:
- break;
- }
- }
- if((pxErr = PXSrchFld(workTable->tblHandle, rch, compSecIndexHandle, mode))
- != PXSUCCESS)
- {
- pxErr = PXRecBufClose(rch);
- return 0;
- }
-
- pxErr = PXRecBufClose(rch);
- return 1;
- }
- ////////////////////////////
- void KH_AskManager::writeField(KH_PXTable* srcTable, KH_PXTable* destTable)
- {
- BLOBHANDLE srcBlob;
- BLOBHANDLE destBlob;
-
- unsigned long size;
- unsigned int workSize;
-
- pxErr = PXBlobOpenRead(srcTable->recHandle, srcTable->fldHandle, &srcBlob);
- pxErr = PXBlobGetSize(srcBlob, &size);
- pxErr = PXBlobOpenWrite(destTable->recHandle, destTable->fldHandle,
- &srcBlob, size, PXBLOBNEW);
- if(size > 65520)
- workSize = 65520;
- else
- workSize = size;
- char* buff = new char[workSize];
- for(long off = 0; off + workSize <= size; off += workSize)
- {
- pxErr = PXBlobGet(srcBlob, workSize, off, buff);
- pxErr = PXBlobPut(destBlob, workSize, off, buff);
- if(size - off > 65520)
- workSize = 65520;
- else
- workSize = size;
- }
- pxErr = PXBlobClose(srcBlob, PXBLOBREJECT);
- pxErr = PXBlobClose(destBlob, PXBLOBACCEPT);
- delete buff;
- }
- ////////////////////////////
- int KH_AskManager::processMultipleTables()
- {
- char buf[255]; // String field of KH_PXFLD structure
- KH_PXFLD* retFld = new KH_PXFLD(buf);// Structure returned by getField in
- // the process of ANSWER building
- int eNums[510]; // EXAMPLES intersections
- FIELDHANDLE exFlds[255];
-
- for(int i = 1; i < numberOfTables; i++) // Sequential processing
- { // i == 1 <= we skip 0th table
- KH_STRTABLE* ex = getExamples(i); // Examples in ANSWER
- KH_STRTABLE* cur = getCurrExamples(i); // and in current table
- int numEx;
- if(!(numEx = getExSrc(ex, cur, eNums, exFlds)))// eNums contains pares:
- { // field No of workTable and of
- delete retFld; // tables[i] containing examples with
- delete cur; // same names. NumEx is 0 if no
- delete ex; // intersections find (error), or
- return 0; // 2 * number of examples on success.
- } // exFlds contains ANSWER EX index flds
-
- delete answerTable; // Old ANSWER will be replaced
- delete workTable;
- pxErr = PXTblRename("answer.db", "answer1.db");
-
- char nm[10];
- itoa(indexNo, nm, 10);
- indexNo++;
- FIELDHANDLE compSecIndexHandle;
- pxErr = PXKeyMap("answer1.db", numEx / 2, exFlds, nm, 0,
- &compSecIndexHandle);
- exFlds[0] = compSecIndexHandle;
-
- pxErr = PXKeyAdd("answer1.db", 1, exFlds, SECONDARY);
-
- if(!createAnswerTable(i + 1)) // Create new ANSWER table
- { // return on fail
- delete retFld;
- delete cur;
- delete ex;
- return 0;
- }
- answerTable = new KH_PXTable("answer.db"); // Build new temp. tables
- workTable = new KH_PXTable("answer1.db", compSecIndexHandle);
-
- KH_STRTABLE* completeQuerry = makeQuerry(i); // Unpacked querry
-
- RECORDNUMBER recNumber;
- pxErr = PXRecFirst(tables[i]->tblHandle);
-
- while((pxErr = PXRecGet(tables[i]->tblHandle, tables[i]->recHandle))
- == PXSUCCESS)
- {
- int mode = SEARCHFIRST;
- pxErr = PXRecFirst(workTable->tblHandle);
- while(moveToRec(eNums, numEx, i, mode, compSecIndexHandle)
- && (pxErr = PXRecGet(workTable->tblHandle,
- workTable->recHandle) == PXSUCCESS))
- {
- mode = SEARCHNEXT;
- if(!tables[i]->testQuerry(completeQuerry->strings))
- break;
- for(int number = 1; number <= workTable->nFlds; number++)
- {
- workTable->setFld(number);
- answerTable->setFld(number);
-
- if(workTable->getField(retFld) == KH_BLOB)
- writeField(workTable, answerTable);
- else
- answerTable->putField(retFld);
- }
- for(int number1 = number, num = 1;
- number1 <= number + tables[i]->nFlds; number1++, num++)
- {
- tables[i]->setFld(num);
- answerTable->setFld(number1);
- if(tables[i]->getField(retFld) == KH_BLOB)
- writeField(tables[i], answerTable);
- else
- answerTable->putField(retFld);
- }
- if((pxErr = PXRecAppend(answerTable->tblHandle,
- answerTable->recHandle))
- != PXSUCCESS)
- {
- delete retFld;
- delete completeQuerry;
- delete cur;
- delete ex;
- return 0;
- }
- }
- if((pxErr = PXRecNext(tables[i]->tblHandle)) != PXSUCCESS)
- break;
- }
- delete completeQuerry;
- delete cur;
- delete ex;
- }
-
- delete retFld;
- return 1;
- }
- /////////////////////////////////
- void KH_AskManager::dumpAnswer()
- {
- char buf[255]; // String field of KH_PXFLD structure
- KH_PXFLD* retFld = new KH_PXFLD(buf);
- delete workTable;
- pxErr = PXTblDelete("answer1.db");
- KH_STRTABLE* fields = new KH_STRTABLE(0, NULL);
- KH_STRTABLE* types = new KH_STRTABLE(0, NULL);
-
- int srcNo = 1;
- char fld[26];
- char typ[26];
- for(int i = 0; i < numberOfTables; i++)
- {
- for(int j = 1; j <= tables[i]->nFlds; j++)
- {
- if(querryList[i]->checkedFields[j] != '\0')
- {
- PXFldName(answerTable->tblHandle, srcNo, 26, fld);
- fields->add(fld);
- PXFldType(answerTable->tblHandle, srcNo, 26, typ);
- types->add(typ);
- srcNo++;
- }
- }
- }
-
- workTable = new KH_PXTable("answer1.db", 0, fields->used,
- fields->strings, types->strings);
-
- pxErr = PXRecFirst(answerTable->tblHandle);
- int fNo;
-
- while((pxErr = PXRecGet(answerTable->tblHandle,
- answerTable->recHandle)) == PXSUCCESS)
- {
- srcNo = fNo = 1;
- for(i = 0; i < numberOfTables; i++)
- {
- for(int j = 1; j <= tables[i]->nFlds; j++)
- {
- if(querryList[i]->checkedFields[j] != '\0')
- {
- answerTable->setFld(srcNo);
- workTable->setFld(fNo);
- if(answerTable->getField(retFld) == KH_BLOB)
- writeField(answerTable, workTable);
- else
- workTable->putField(retFld);
- fNo++;
- }
- srcNo++;
- }
- }
- pxErr = PXRecAppend(workTable->tblHandle, workTable->recHandle);
- if((pxErr = PXRecNext(answerTable->tblHandle)) != PXSUCCESS)
- break;
-
- }
- delete retFld;
- delete fields;
- delete types;
- delete workTable;
- delete answerTable;
- pxErr = PXTblRename("answer1.db", "answer.db");
- workTable = NULL;
- answerTable = NULL;
- }
- /////////////////////////////////
- int KH_AskManager::process()
- {
- if(!checkQuerry()) // Verification.
- return 0;
-
- if(!createAnswerTable(1)) // Create ANSWER table
- return 0;
- answerTable = new KH_PXTable("answer.db");
- int ret = processSingleTable();
-
- if(ret && numberOfTables > 1)
- ret = processMultipleTables();
-
- dumpAnswer();
-
- return ret;
- }
-
-
-
-
- #include <iostream.h>
- #include <time.h>
- /////////////////////
- /*
- void main()
- {
- // Init PARADOX ENGINE
- if(PXInit() != PXSUCCESS)
- return;
- // Process single-table querry to DEMO.DB table
- char* tableNames[] = { "demo.db" }; // Table name
-
- char* q[] = { "", "", "", "", "", "", "", "", "" }; // Querries
- char* e[] = { "", "", "", "", "", "", "", "", "" }; // Examples
- char* c = "\2\2\2\2\2\2\2\2\2\2\0"; // Checkers
-
- KH_QUERRY* querry1 = new KH_QUERRY(q, e, c, 5); // Build querry
- KH_QUERRY* querries[2]; // Querry list
- querries[0] = querry1;
- KH_AskManager* ask = new KH_AskManager(tableNames, querries, 1);
-
- ask->process(); // Process querry, get ANSWER table
- ////////////
-
- KH_PXTable table("answer.db");
-
- char* shablon[] = { "", "", "", "", "", "", "", "", "", "", "" };
- char buf[255];
- int eot;
- while(table.Find(shablon) == 1)
- {
- for(int i = 2; i < 5; i++)
- {
- table.setFld(i);
- table.TranslateField(buf);
- cout << buf << '\t';
- }
- cout << "\n";
- }
-
-
- delete ask;
- delete querry1;
-
- unlink("answer.db");
- PXExit();
- }
- */
-
- void main()
- {
- // Init PARADOX ENGINE
- if(PXInit() != PXSUCCESS)
- return;
- indexNo = 0; // ATTENTION !!! Absolutely necessary for multytable
- // querries.
- // Process single-table querry to DEMO.DB table
- char* tableNames[] = { "demo.db", "demo.db", "demo.db" }; // Table name
-
- char* q[] = { "", "", "", "", "", "", "", "", "" }; // Querries
- char* e[] = { "", "", "X", "", "", "", "", "", "" }; // Examples
- char* c = "\2\2\2\2\2\2\2\2\2\2\0"; // Checkers
-
- KH_QUERRY* querry1 = new KH_QUERRY(q, e, c, 5); // Build querry
- KH_QUERRY* querries[3]; // Querry list
- querries[0] = querry1;
- querries[1] = querry1;
- querries[2] = querry1;
- KH_AskManager* ask = new KH_AskManager(tableNames, querries, 3);
-
- time_t first, second;
-
- first = time(NULL);
- ask->process(); // Process querry, get ANSWER table
- second = time(NULL);
- cout << "\nProcessing time = " << difftime(second,first) << " seconds \n";
- ////////////
-
- KH_PXTable table("answer.db");
-
- char* shablon[] = { "", "", "", "", "", "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "", "", "", "", "", "" };
- char buf[255];
- int eot;
- long l = 0;
- while(table.Find(shablon) == 1)
- {
- for(int i = 1; i < 16; i++)
- {
- table.setFld(i);
- table.TranslateField(buf);
- cout << i << ": " << buf << "\n";
- }
- cout << "<<<<<<<<<<<<< RECORD " << l << " >>>>>>>>>>>>>>>>\n";
- l++;
- }
-
-
- delete ask;
- delete querry1;
-
- unlink("answer.db");
- PXExit();
- }
-
- /*
- void main() // Add operations on BLOB fields
- {
- // Init PARADOX ENGINE
- if(PXInit() != PXSUCCESS)
- return;
- // Process single-table querry to DEMO.DB table
- char* tableNames[] = { "demo.db" }; // Table name
-
- char* q[] = { "", "", "", "", "", "", "", "", "" }; // Querries
- char* e[] = { "", "", "", "", "", "", "", "", "" }; // Examples
- char* c = "\2\2\2\2\2\2\2\2\2\2\0"; // Checkers
-
- KH_QUERRY* querry1 = new KH_QUERRY(q, e, c, 5); // Build querry
- KH_QUERRY* querries[2]; // Querry list
- querries[0] = querry1;
- KH_AskManager* ask = new KH_AskManager(tableNames, querries, 1);
-
- ask->process(); // Process querry, get ANSWER table
- ////////////
-
- KH_PXTable table("answer.db");
-
- char* shablon[] = { "", "", "", "", "", "", "", "", "", "", "" };
- char buf[255];
- char buf1[255];
- int eot;
- KH_PXFLD* retFld = new KH_PXFLD(buf1);
- while(table.Find(shablon) == 1)
- {
- for(int i = 1; i < 6; i++)
- {
- table.setFld(i);
- if(table.TranslateField(buf) == KH_BLOB)
- {
- table.getField(retFld);
- cout << "***************** BLOB: " << retFld->str << "\n";
- }
- else
- cout << buf << "\n";
- }
- cout << "<<<<<<<<<<<<<<<<<<<<<<<<\n";
- }
-
- delete retFld;
- delete ask;
- delete querry1;
-
- unlink("answer.db");
- PXExit();
- }
- */
- /*
- void main()
- {
- // Init PARADOX ENGINE
- if(PXInit() != PXSUCCESS)
- return;
- indexNo = 0; // ATTENTION !!! Absolutely necessary for multytable
- // querries.
- char buf1[255];
- KH_PXFLD* retFld = new KH_PXFLD(buf1);
-
- // Process single-table querry to DEMO.DB table
- char* tableNames[] = { "demo.db", "demo.db", "demo.db" }; // Table name
-
- char* q[] = { "", "", "", "", "", "", "", "", "" }; // Querries
- char* e[] = { "", "", "X", "", "", "", "", "", "" }; // Examples
- char* c = "\2\2\2\2\2\2\2\2\2\2\0"; // Checkers
-
- KH_QUERRY* querry1 = new KH_QUERRY(q, e, c, 5); // Build querry
- KH_QUERRY* querries[3]; // Querry list
- querries[0] = querry1;
- querries[1] = querry1;
- querries[2] = querry1;
- KH_AskManager* ask = new KH_AskManager(tableNames, querries, 3);
-
- time_t first, second;
-
- first = time(NULL);
- ask->process(); // Process querry, get ANSWER table
- second = time(NULL);
- cout << "\nProcessing time = " << difftime(second,first) << " seconds \n";
- ////////////
-
- KH_PXTable table("answer.db");
-
- char* shablon[] = { "", "", "", "", "", "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "", "", "", "", "", "" };
- char buf[255];
- int eot;
- long l = 0;
- while(table.Find(shablon) == 1)
- {
- for(int i = 1; i < 16; i++)
- {
- table.setFld(i);
- if(table.TranslateField(buf) == KH_BLOB)
- {
- table.getField(retFld);
- cout << "***************** BLOB: " << retFld->str << "\n";
- }
- else
- cout << i << ": " << buf << "\n";
- }
- cout << "<<<<<<<<<<<<< RECORD " << l << " >>>>>>>>>>>>>>>>\n";
- l++;
- }
-
- delete retFld;
- delete ask;
- delete querry1;
-
- unlink("answer.db");
- PXExit();
- }
-
- */